#include "asio_header.h"
#include "asio_Server.h"
#include "asio_NetworkHandler.h"
#include "ServerHandler.h"

namespace XGC
{
	namespace net
	{

		asio_Server::asio_Server( IMessageQueue* pMessageQueue, _uint32 timeout )
			: acceptor_( service_, ip::tcp::v4() )
			, m_pMessageQueue( pMessageQueue )
			, timeout_( timeout )
		{
		}

		asio_Server::~asio_Server(void)
		{
			acceptor_.close();
		}

		bool asio_Server::StartServer( const char *address, short port )
		{
			system::error_code ec;
			ip::address_v4 addr = ip::address_v4::from_string( address, ec );
			if( ec )
				return false;

			acceptor_.bind( ip::tcp::endpoint( addr, port ), ec );
			if( ec )
				return false;

			acceptor_.listen( 10, ec );
			if( ec )
				return false;

			for( int i = 0; i < 10; ++i )
			{
				asio_NetworkHandlerPtr pNetHandler( new asio_NetworkHandler(service_, new CServerHandler( m_pMessageQueue ) ) );
				acceptor_.async_accept(pNetHandler->socket(), boost::bind(&asio_Server::handle_accept, this, pNetHandler, asio::placeholders::error) );
			}
			service_.run();
			return true;
		}

		void asio_Server::StopServer()
		{
			service_.post( bind(&asio_Server::handle_stop, this) );
		}

		void asio_Server::handle_accept( asio_NetworkHandlerPtr pNetHandler, const system::error_code& error)
		{
			if (!error)
			{
				pNetHandler->accpet();
				asio_NetworkHandlerPtr pNetHandler(new asio_NetworkHandler(service_, new CServerHandler( m_pMessageQueue ) ) );
				acceptor_.async_accept(pNetHandler->socket(), boost::bind(&asio_Server::handle_accept, this, pNetHandler, asio::placeholders::error));
			}
		}

		void asio_Server::handle_stop()
		{
			acceptor_.close();
		}
	}

	//----------------------------------------------------------------
	namespace net
	{

		asio_ServerEx::asio_ServerEx( create_handler_func call, long_ptr param, _uint32 timeout )
			: acceptor_( service_, ip::tcp::v4() )
			, call_( call )
			, param_( param )
			, timeout_( timeout )
		{
		}

		asio_ServerEx::~asio_ServerEx(void)
		{
			acceptor_.close();
		}

		bool asio_ServerEx::StartServer( const char *address, short port )
		{
			system::error_code ec;
			ip::address_v4 addr = ip::address_v4::from_string( address, ec );
			if( ec )
				return false;

			acceptor_.bind( ip::tcp::endpoint( addr, port ), ec );
			if( ec )
				return false;

			acceptor_.listen( 10, ec );
			if( ec )
				return false;

			for( int i = 0; i < 10; ++i )
			{
				asio_NetworkHandler *pNetHandler = new asio_NetworkHandler(service_, call_( param_ ) );
				acceptor_.async_accept(pNetHandler->socket(), boost::bind(&asio_ServerEx::handle_accept, this, pNetHandler, asio::placeholders::error) );
			}

			service_.run();
			return true;
		}

		void asio_ServerEx::StopServer()
		{
			service_.post( bind( &asio_ServerEx::handle_stop, this ) );
		}

		void asio_ServerEx::handle_accept( asio_NetworkHandler *pNetHandler, const system::error_code& error)
		{
			if (!error)
			{
				pNetHandler->accpet();
				asio_NetworkHandler *pNetHandler(new asio_NetworkHandler(service_, call_( param_ ) ) );
				acceptor_.async_accept(pNetHandler->socket(), boost::bind(&asio_ServerEx::handle_accept, this, pNetHandler, asio::placeholders::error));
			}
		}

		void asio_ServerEx::handle_stop()
		{
			acceptor_.close();
		}

	}

}